package com.zhj.common.web.async;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.annotation.PostConstruct;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author zhj
 */
@ConfigurationProperties(prefix = "async.executor")
@Data
public class AsyncExecutorConfiguration {

    /**
     * 核心线程数
     */
    private Integer coreNum;

    /**
     * 最大线程数
     */
    private Integer maxNum;

    /**
     * 最大超时时间（秒）
     */
    private Integer maxTimeoutSec = 300;

    /**
     * 是否允许核心线程数超时
     */
    private Boolean allowCoreThreadTimeOut = false;

    /**
     * 线程名称的前缀
     */
    private String threadNamePrefix = "Base-Executor-";

    /**
     * 阻塞队列的最大容量
     */
    private Integer queueCapacity = 1000;

    private RejectEnum rejectHandler = RejectEnum.CALLER_RUNS_POLICY;

    @PostConstruct
    public void init() {
        // CPU核心数
        int core = Runtime.getRuntime().availableProcessors();
        // 配置核心线程数 CPU密集型
        if (coreNum == null || coreNum <= 0)
            this.coreNum = core;
        // 配置最大线程数 IO密集型
        if (maxNum == null || maxNum <= 0)
            this.maxNum = core * 2;
    }

    /**
     * 拒绝策略枚举
     */
    public enum RejectEnum {

        // 抛出异常的方式
        ABORT_POLICY(new ThreadPoolExecutor.AbortPolicy()),
        // 提交任务的线程自行执行该任务
        CALLER_RUNS_POLICY(new ThreadPoolExecutor.CallerRunsPolicy()),
        // 线程池会放弃阻塞队列，最久的任务
        DISCARD_OLDEST_POLICY(new ThreadPoolExecutor.DiscardOldestPolicy()),
        // 直接丢弃当前拒绝的任务
        DISCARD_POLICY(new ThreadPoolExecutor.DiscardPolicy())
        ;

        private RejectedExecutionHandler rejectedExecutionHandler;

        RejectEnum(RejectedExecutionHandler rejectedExecutionHandler) {
            this.rejectedExecutionHandler = rejectedExecutionHandler;
        }

        public RejectedExecutionHandler getRejectedExecutionHandler() {
            return rejectedExecutionHandler;
        }
    }
}
